using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Domain.Entities;
using JGSY.CMS.LowCode.Platform.Domain.Interfaces;
using JGSY.CMS.LowCode.Platform.Infrastructure.CmsDbContext;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Repositories
{
    /// <summary>
    /// 产品仓储实现
    /// 提供产品管理的完整数据访问功能，包含库存管理、销售统计等企业级功�?
    /// </summary>
    public class ProductRepository : Repository<Product>, IProductRepository
    {
        private readonly ILogger<ProductRepository>? _logger;

        public ProductRepository(LowCodeDbContext context, ILogger<ProductRepository>? logger = null) : base(context)
        {
            _logger = logger;
        }

        #region IProductRepository 实现

        /// <summary>
        /// 获取所有产品记�?
        /// </summary>
        public override async Task<List<Product>> GetAllAsync()
        {
            return await _context.Products
                .Where(p => p.Status != 0) // 排除已删�?
                .OrderByDescending(p => p.CreatedAt)
                .ToListAsync();
        }

        async Task<IEnumerable<Product>> IProductRepository.GetAllAsync()
            => await GetAllAsync();

        /// <summary>
        /// 根据ID获取产品记录
        /// </summary>
    public async Task<Product?> GetByIdAsync(long id)
        {
            return await _context.Products
                .FirstOrDefaultAsync(p => p.Id == id && p.Status != 0);
        }

        /// <summary>
        /// 根据SKU获取产品记录
        /// </summary>
        public async Task<Product?> GetBySkuAsync(string sku)
        {
            return await _context.Products
                
                .FirstOrDefaultAsync(p => p.Sku == sku && p.Status != 0);
        }

        /// <summary>
        /// 根据分类获取产品列表
        /// </summary>
        public async Task<IEnumerable<Product>> GetByCategoryAsync(long categoryId)
        {
            return await _context.Products
                
                .Where(p => p.CategoryId == categoryId && p.Status == 1)
                .OrderByDescending(p => p.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 搜索产品
        /// </summary>
    public async Task<IEnumerable<Product>> SearchAsync(string keyword)
        {
            return await _context.Products
                
        .Where(p => p.Status == 1 &&
               (p.Name.Contains(keyword) ||
                (p.Description != null && p.Description.Contains(keyword)) ||
                (p.Sku != null && p.Sku.Contains(keyword))))
                .OrderByDescending(p => p.SalesCount)
                .ToListAsync();
        }

        /// <summary>
        /// 获取热销产品
        /// </summary>
        public async Task<IEnumerable<Product>> GetBestSellersAsync(int count = 10)
        {
            return await _context.Products
                
                .Where(p => p.Status == 1)
                .OrderByDescending(p => p.SalesCount)
                .Take(count)
                .ToListAsync();
        }

        /// <summary>
        /// 获取最新产�?
        /// </summary>
        public async Task<IEnumerable<Product>> GetLatestProductsAsync(int count = 10)
        {
            return await _context.Products
                
                .Where(p => p.Status == 1)
                .OrderByDescending(p => p.CreatedAt)
                .Take(count)
                .ToListAsync();
        }

        /// <summary>
        /// 获取低库存产�?
        /// </summary>
        public async Task<IEnumerable<Product>> GetLowStockProductsAsync(int threshold = 10)
        {
            return await _context.Products
                
                .Where(p => p.Status == 1 && p.Stock <= threshold && p.Stock > 0)
                .OrderBy(p => p.Stock)
                .ToListAsync();
        }

        /// <summary>
        /// 分页获取产品列表
        /// </summary>
        public async Task<(IEnumerable<Product> Items, int TotalCount)> GetPagedAsync(
            int pageIndex, 
            int pageSize, 
            string? keyword = null, 
            long? categoryId = null, 
            decimal? minPrice = null, 
            decimal? maxPrice = null, 
            string sortBy = "CreatedAt", 
            bool sortDesc = false)
        {
            var query = _context.Products
                
                .Where(p => p.Status == 1);

            // 关键词搜�?
            if (!string.IsNullOrWhiteSpace(keyword))
            {
                query = query.Where(p => p.Name.Contains(keyword) ||
                                   (p.Description != null && p.Description.Contains(keyword)) ||
                                   (p.Sku != null && p.Sku.Contains(keyword)));
            }

            // 分类过滤
            if (categoryId.HasValue)
            {
                query = query.Where(p => p.CategoryId == categoryId.Value);
            }

            // 价格过滤
            if (minPrice.HasValue)
            {
                query = query.Where(p => p.Price >= minPrice.Value);
            }

            if (maxPrice.HasValue)
            {
                query = query.Where(p => p.Price <= maxPrice.Value);
            }

            // 排序
            query = sortBy.ToLower() switch
            {
                "name" => sortDesc ? query.OrderByDescending(p => p.Name) : query.OrderBy(p => p.Name),
                "price" => sortDesc ? query.OrderByDescending(p => p.Price) : query.OrderBy(p => p.Price),
                "stock" => sortDesc ? query.OrderByDescending(p => p.Stock) : query.OrderBy(p => p.Stock),
                "salescount" => sortDesc ? query.OrderByDescending(p => p.SalesCount) : query.OrderBy(p => p.SalesCount),
                "createdat" => sortDesc ? query.OrderByDescending(p => p.CreatedAt) : query.OrderBy(p => p.CreatedAt),
                _ => query.OrderByDescending(p => p.CreatedAt)
            };

            var totalCount = await query.CountAsync();
            var items = await query
                .Skip(pageIndex * pageSize)
                .Take(pageSize)
                .ToListAsync();

            return (items, totalCount);
        }

        /// <summary>
        /// 添加新产�?
        /// </summary>
    public override async Task<Product> AddAsync(Product entity)
        {
            try
            {
                entity.CreatedAt = DateTime.UtcNow;
                entity.UpdatedAt = DateTime.UtcNow;
                
        await base.AddAsync(entity);
                await SaveChangesAsync();
                
                _logger?.LogInformation("Product added successfully with ID: {ProductId}", entity.Id);
        return entity;
        }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to add product with name: {ProductName}", entity.Name);
                throw;
            }
        }

        // 显式接口实现：接口为 Task 版本
        async Task IProductRepository.AddAsync(Product entity)
        {
            _ = await AddAsync(entity);
        }

        /// <summary>
        /// 更新产品信息
        /// </summary>
    public override async Task<Product> UpdateAsync(Product entity)
        {
            try
            {
                entity.UpdatedAt = DateTime.UtcNow;
                _context.Products.Update(entity);
                await SaveChangesAsync();
                
                _logger?.LogInformation("Product updated successfully with ID: {ProductId}", entity.Id);
        return entity;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to update product with ID: {ProductId}", entity.Id);
                throw;
            }
        }

        // 显式接口实现：接口为 Task 版本
        async Task IProductRepository.UpdateAsync(Product entity)
        {
            _ = await UpdateAsync(entity);
        }

        /// <summary>
        /// 删除产品
        /// </summary>
        public async Task DeleteAsync(long id)
        {
            try
            {
                var product = await _context.Products.FindAsync(id);
                if (product != null)
                {
                    product.Status = 0; // 软删�?
                    product.UpdatedAt = DateTime.UtcNow;
                    await SaveChangesAsync();
                    
                    _logger?.LogInformation("Product soft deleted successfully with ID: {ProductId}", id);
                }
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to delete product with ID: {ProductId}", id);
                throw;
            }
        }

        /// <summary>
        /// 批量删除产品
        /// </summary>
        public async Task<int> BatchDeleteAsync(IEnumerable<long> ids)
        {
            try
            {
                var products = await _context.Products
                    .Where(p => ids.Contains(p.Id) && p.Status != 0)
                    .ToListAsync();

                foreach (var product in products)
                {
                    product.Status = 0; // 软删�?
                    product.UpdatedAt = DateTime.UtcNow;
                }

                var deletedCount = products.Count;
                await SaveChangesAsync();
                
                _logger?.LogInformation("Batch deleted {DeletedCount} products", deletedCount);
                return deletedCount;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to batch delete products");
                throw;
            }
        }

        /// <summary>
        /// 更新产品库存
        /// </summary>
        public async Task<bool> UpdateStockAsync(long id, int stock)
        {
            try
            {
                var product = await _context.Products.FindAsync(id);
                if (product != null)
                {
                    product.Stock = stock;
                    product.UpdatedAt = DateTime.UtcNow;
                    await SaveChangesAsync();
                    
                    _logger?.LogInformation("Product stock updated successfully. ID: {ProductId}, Stock: {Stock}", id, stock);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to update stock for product ID: {ProductId}", id);
                return false;
            }
        }

        /// <summary>
        /// 增加产品库存
        /// </summary>
        public async Task<bool> IncreaseStockAsync(long id, int quantity)
        {
            try
            {
                var product = await _context.Products.FindAsync(id);
                if (product != null)
                {
                    product.Stock += quantity;
                    product.UpdatedAt = DateTime.UtcNow;
                    await SaveChangesAsync();
                    
                    _logger?.LogInformation("Product stock increased successfully. ID: {ProductId}, Quantity: +{Quantity}", id, quantity);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to increase stock for product ID: {ProductId}", id);
                return false;
            }
        }

        /// <summary>
        /// 减少产品库存
        /// </summary>
        public async Task<bool> DecreaseStockAsync(long id, int quantity)
        {
            try
            {
                var product = await _context.Products.FindAsync(id);
                if (product != null && product.Stock >= quantity)
                {
                    product.Stock -= quantity;
                    product.UpdatedAt = DateTime.UtcNow;
                    await SaveChangesAsync();
                    
                    _logger?.LogInformation("Product stock decreased successfully. ID: {ProductId}, Quantity: -{Quantity}", id, quantity);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to decrease stock for product ID: {ProductId}", id);
                return false;
            }
        }

        /// <summary>
        /// 增加产品销�?
        /// </summary>
        public async Task<bool> IncreaseSalesAsync(long id, int quantity = 1)
        {
            try
            {
                var product = await _context.Products.FindAsync(id);
                if (product != null)
                {
                    product.SalesCount += quantity;
                    product.UpdatedAt = DateTime.UtcNow;
                    await SaveChangesAsync();
                    
                    _logger?.LogInformation("Product sales increased successfully. ID: {ProductId}, Quantity: +{Quantity}", id, quantity);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to increase sales for product ID: {ProductId}", id);
                return false;
            }
        }

        /// <summary>
        /// 检查SKU是否存在
        /// </summary>
        public async Task<bool> SkuExistsAsync(string sku, long? excludeId = null)
        {
            var query = _context.Products.Where(p => p.Sku != null && p.Sku == sku && p.Status != 0);
            
            if (excludeId.HasValue)
            {
                query = query.Where(p => p.Id != excludeId.Value);
            }
            
            return await query.AnyAsync();
        }

        /// <summary>
        /// 获取产品销售统�?
        /// </summary>
        public async Task<(int TotalProducts, int ActiveProducts, int LowStockProducts, decimal TotalValue)> GetSalesStatisticsAsync()
        {
            try
            {
                var totalProducts = await _context.Products.CountAsync(p => p.Status != 0);
                var activeProducts = await _context.Products.CountAsync(p => p.Status == 1);
                var lowStockProducts = await _context.Products.CountAsync(p => p.Status == 1 && p.Stock <= 10);
                var totalValue = await _context.Products
                    .Where(p => p.Status == 1)
                    .SumAsync(p => p.Price * p.Stock);

                return (totalProducts, activeProducts, lowStockProducts, totalValue);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Failed to get product sales statistics");
                return (0, 0, 0, 0);
            }
        }

        public async Task<Product?> GetBySlugAsync(string slug)
        {
            return await _context.Products
                .FirstOrDefaultAsync(p => p.Slug == slug && p.Status != 0);
        }

        public async Task<IEnumerable<Product>> GetFeaturedProductsAsync(int count = 10)
        {
            return await _context.Products
                .Where(p => p.Status == 1) // 使用上架状态作为精选产品的条件
                .OrderBy(p => p.SortOrder)
                .Take(count)
                .ToListAsync();
        }

        public async Task<IEnumerable<Product>> GetBestSellingProductsAsync(int count = 10)
        {
            return await _context.Products
                .Where(p => p.Status == 1)
                .OrderByDescending(p => p.SalesCount)
                .Take(count)
                .ToListAsync();
        }

    public async Task<(IEnumerable<Product> Items, int TotalCount)> GetPagedAsync(int pageIndex, int pageSize, string? keyword = null, long? categoryId = null, byte? status = null, decimal? minPrice = null, decimal? maxPrice = null, string? sortBy = null, bool sortDesc = false)
        {
            var query = _context.Products.AsQueryable();

            if (!string.IsNullOrEmpty(keyword))
            {
        query = query.Where(p => p.Name.Contains(keyword) || (p.Description != null && p.Description.Contains(keyword)));
            }

            if (categoryId.HasValue)
            {
                query = query.Where(p => p.CategoryId == categoryId);
            }

            if (status.HasValue)
            {
                query = query.Where(p => p.Status == status);
            }

            if (minPrice.HasValue)
            {
                query = query.Where(p => p.Price >= minPrice);
            }

            if (maxPrice.HasValue)
            {
                query = query.Where(p => p.Price <= maxPrice);
            }

            var totalCount = await query.CountAsync();

            // 排序
            if (!string.IsNullOrEmpty(sortBy))
            {
                switch (sortBy.ToLower())
                {
                    case "name":
                        query = sortDesc ? query.OrderByDescending(p => p.Name) : query.OrderBy(p => p.Name);
                        break;
                    case "price":
                        query = sortDesc ? query.OrderByDescending(p => p.Price) : query.OrderBy(p => p.Price);
                        break;
                    case "sales":
                        query = sortDesc ? query.OrderByDescending(p => p.SalesCount) : query.OrderBy(p => p.SalesCount);
                        break;
                    default:
                        query = sortDesc ? query.OrderByDescending(p => p.CreatedAt) : query.OrderBy(p => p.CreatedAt);
                        break;
                }
            }
            else
            {
                query = query.OrderByDescending(p => p.CreatedAt);
            }

            var items = await query
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            return (items, totalCount);
        }

        public async Task<bool> IncrementSalesCountAsync(long id, int quantity = 1)
        {
            var product = await _context.Products.FindAsync(id);
            if (product == null) return false;

            product.SalesCount += quantity;
            product.UpdatedAt = DateTime.UtcNow;

            await _context.SaveChangesAsync();
            return true;
        }

        public async Task<bool> SlugExistsAsync(string slug, long? excludeId = null)
        {
            var product = await _context.Products
                .FirstOrDefaultAsync(p => p.Slug == slug && 
                                        p.Status != 0 &&
                                        (excludeId == null || p.Id != excludeId));
            return product != null;
        }

    public async Task<(IEnumerable<Product> Items, int TotalCount)> SearchAsync(string keyword, int pageIndex = 1, int pageSize = 20)
        {
            var query = _context.Products
                .Where(p => p.Status != 0 && 
              (p.Name.Contains(keyword) ||
               (p.Description != null && p.Description.Contains(keyword)) ||
               (p.Tags != null && p.Tags.Contains(keyword))));

            var totalCount = await query.CountAsync();
            var items = await query
                .OrderByDescending(p => p.CreatedAt)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            return (items, totalCount);
        }

        #endregion
    }
}
